#include "stdafx.h"
#include "AircraftType.h"
#include "Aircraft.h"
#include "GateStand.h"
#include "Flight.h"
#include "Time.h"
#include <list>
#include <iostream>

#ifndef EMPTY
#define EMPTY 0
#define OCCUPIED 1
#endif

using namespace std;

/*------------------------------------------------------------
/ Gate Stand Class
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: A definition of the Gate Stand Class. Defines the
/ extended attributes deallocation time, current aircraft, and 
/ accomodation list, as well as defining getter and setter methods 
/ for most, with a few methods specific to the list
------------------------------------------------------------*/

/*------------------------------------------------------------
/ Constructor
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: Instantiates any gate stand object
/ Paramneters: stand ID, deallocation time
/ Return: N/A
------------------------------------------------------------*/
GateStand::GateStand(std::string stID)
{
	standID = stID;
	standStatus = EMPTY;
	typeList = new list<AircraftType> ();
	currentAircraft = new Aircraft ();
}

/*------------------------------------------------------------
/ Constructor
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: Instantiates any gate stand object
/ Paramneters: stand ID, deallocation time
/ Return: N/A
------------------------------------------------------------*/
GateStand::GateStand(std::string stID, list<AircraftType> *tList)
{
	standID = stID;
	standStatus = EMPTY;
	typeList = tList;
	currentAircraft = new Aircraft ();
}

/*------------------------------------------------------------
/ Destructor
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: Destroys a gate stand object
/ Paramneters: N/A
/ Return: N/A
------------------------------------------------------------*/
GateStand::~GateStand(void)
{
}

/*------------------------------------------------------------
/ getAccomodationList
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: returns a list of associated flight
/ Paramneters: N/A
/ Return: the accomodation list
------------------------------------------------------------*/
std::list<Flight>* GateStand::getAccomodationList (void){
	std::list <Flight>* tList;
	tList = accomodationList;
	return tList;
}

/*------------------------------------------------------------
/ getCurrentAircraft
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: returns the aircraft present
/ Paramneters: N/A
/ Return: the current aircraft
------------------------------------------------------------*/
Aircraft* GateStand::getCurrentAircraft (void){
	return currentAircraft;
}

/*------------------------------------------------------------
/ setCurrentAircraft
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: sets the current aircraft
/ Paramneters: the aircraft
/ Return: N/A
------------------------------------------------------------*/
void GateStand::setCurrentAircraft (Aircraft *plane){
	if (currentAircraft->getAircraftID() == -1){
		currentAircraft->~Aircraft();
		currentAircraft = plane;
	}else{
		printf ("ERROR IN GATESTAND.CPP! REPLACING EXISTING AIRCRAFT AT STAND BEFORE IT HAS LEFT\n");
	}
}

/*------------------------------------------------------------
/ setCurrentAircraft
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: sets the current aircraft to null
/ Paramneters: the aircraft
/ Return: N/A
------------------------------------------------------------*/
void GateStand::setCurrentAircraft (){
	currentAircraft = new Aircraft ();
}

/*------------------------------------------------------------
/ addFlightToList
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: adds a flight to the accomodation list
/ Paramneters: the new flight
/ Return: N/A
------------------------------------------------------------*/
void GateStand::addFlightToList (Flight newFlight){
	//Add code to put the flight in the proper part of the list
	std::list<Flight>::iterator it;
	int flag = 0;
	Time newFlightTime;
	
	//sets the reference time to the arrival time
	if (newFlight.getArrivalTime() != NULL){
		newFlightTime.setH(newFlight.getArrivalTime()->getH());
		newFlightTime.setM(newFlight.getArrivalTime()->getM());
	//Sets the reference time to the departture time
	}else{
		newFlightTime.setH(newFlight.getDepartureTime()->getH());
		newFlightTime.setM(newFlight.getDepartureTime()->getM());
	}

	//if the list is empty, just add it
	if (accomodationList->empty()){
	accomodationList->push_back(newFlight);

	//if the list is not empty, search for proper location
	}else{
		it = accomodationList->begin();

		//find the position for the flight object in the list
		while (!flag && it != accomodationList->end()){

			/* ADD IN THE INFORMATION FOR DATE, WHEN IT BECOMES AVAILABLE
			* DO NOT FORGET!!!!!!!!!!!!!!!!!!!!!
			* DO NOT FORGET!!!!!!!!!!!!!!!!!!!!!
			* DO NOT FORGET!!!!!!!!!!!!!!!!!!!!!
			* DO NOT FORGET!!!!!!!!!!!!!!!!!!!!!
			* DO NOT FORGET!!!!!!!!!!!!!!!!!!!!!
			* DO NOT FORGET!!!!!!!!!!!!!!!!!!!!!
			*/
			if (it->getArrivalTime() != NULL){
				//Checks if hour of current node is earlier than flight object 
				if (it->getArrivalTime()->getH() > newFlightTime.getH()){
					it++; //move to next node

				//if hours are equal check minutes
				} else if (it->getArrivalTime()->getH() == newFlightTime.getH()) {
						if (it->getArrivalTime()->getM() > newFlightTime.getM()){
							it++; //move to next node
						} else {
							flag++; //found the correct position for the flight object
						}		
				} else {
					flag++; //found the correct position for the flight object
				}
			}else{
				//Checks if hour of current node is earlier than flight object 
				if (it->getDepartureTime()->getH() > newFlightTime.getH()){
					it++; //move to next node

				//if hours are equal check minutes
				} else if (it->getDepartureTime()->getH() == newFlightTime.getH()) {
						if (it->getDepartureTime()->getM() > newFlightTime.getM()){
							it++; //move to next node
						} else {
							flag++; //found the correct position for the flight object
						}		
				} else {
					flag++; //found the correct position for the flight object
				}
			}
		}

		//compare against the last element of the list
		if (!flag){
			//CHECK FOR ARRIVAL FLIGHTS
			if (it->getArrivalTime() != NULL){
				//if the hours are earlier, this is the spot so set flag
				if (!(it->getArrivalTime()->getH() > newFlightTime.getH())){
					flag ++;
				//if not, check minutes
				}else{
					//the hours are the same, see if minutes are before, if so, we found our spot
					if (it->getArrivalTime()->getH() == newFlightTime.getH()){
						if (!(it->getArrivalTime()->getM() > newFlightTime.getM())){
							flag ++;
						}
					}	
				}
			//CHECK FOR DEPARTING FLIGHTS
			}else{
				//if the hours are earlier, this is the spot so set flag
				if (!(it->getDepartureTime()->getH() > newFlightTime.getH())){
					flag ++;
				//if not, check minutes
				}else{
					//the hours are the same, see if minutes are before, if so, we found our spot
					if (it->getDepartureTime()->getH() == newFlightTime.getH()){
						if (!(it->getDepartureTime()->getM() > newFlightTime.getM())){
							flag ++;
						}
					}	
				}
			}
		}

		//if spot has been found, add to location
		if (flag){
			accomodationList->insert(it,newFlight);

		//if no spot found, add to the end of the list
		}else{
			accomodationList->push_back(newFlight);
		}
	}
}

/*------------------------------------------------------------
/ removeFlightFromList
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: removes a flight from the list if present
/ Paramneters: the flight
/ Return: 0 if completed, -1 if failure
------------------------------------------------------------*/
int GateStand::removeFlightFromList (Flight deleteFlight){
	//ADD CODE TO ENSURE THAT THE FLIGHT IS ACTUALLY PRESENT 
	//BEFORE TRYING TO DELETE IT -- RETURN NEGATIVE IF FAILED
	std::list<Flight>::iterator it;
	int flag = 0;

	//if the list is empty, just add it
	if (accomodationList->empty()){
		std::cout << "ERROR IN GATESTAND.CPP, THE ITEM ATTEMPTED TO BE REMOVED FOR DOESNT EXIST! SHOULD NEVER HAPPEN!" << std::endl;
		return -1; //The List Is Empty, the item does not exist ERROR

	//if the list is not empty, search for proper location
	}else{
		it = accomodationList->begin();

		//find the position for the flight object in the list
		while (it != accomodationList->end()){
			if (it->getFlightID() == deleteFlight.getFlightID()){
				accomodationList->erase(it);
				return 1;
			}
		}
		   
		//compare against the last element of the list, if it is equal, remove it
		if (it->getFlightID() == deleteFlight.getFlightID()){
			accomodationList->erase(it);
			return 1;
		//if not equal, error
		}else{
			std::cout << "ERROR IN SCHEDULE.CPP, THE ITEM ATTEMPTED TO BE REMOVED FOR DOESNT EXIST! SHOULD NEVER HAPPEN!" << std::endl;
			return -1;
		}
	}
}

/*------------------------------------------------------------
/ flightCompleted
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: advances the flight after the aircraft departs or arrives
/ Paramneters: N/A
/ Return: N/A
------------------------------------------------------------*/
void GateStand::flightCompleted (){
	//THIS IS MEANT TO ADVANCE TO THE NEXT FLIGHT AFTER AN 
	//AIRCRAFT LEAVES THE GATE, BASICALLY JUST AN EASY WAY
	//TO REMOVE THE FRONT FLIGHT, CHANGE THE CURRENT AIRCRAFT 
	//TO NULL, AND REMOVE THE FLIGHT FROM THE ACCOMODATION LIST
	//WHILE MAKING THE NEXT FLIGHT THE NEW FRONT OF THE LIST
	Flight firstFlight = accomodationList->front();
	accomodationList->pop_front();
	if (firstFlight.getArrivalTime() == NULL){
		//currentAircraft = NULL;
	}
<<<<<<< .mine
}



/*------------------------------------------------------------
/ getTypeList
/ By: Trevor
/ Date: February 29 2011
/ Description: 
/ Parameters: none
/ Return: pointer to a list of aircraft types accomodated by this stand
------------------------------------------------------------*/	
std::list<AircraftType>* GateStand::getTypeList(){
	return typeList;

}

/*------------------------------------------------------------
/ setTypeList			
/ By: Trevor
/ Date: February 29 2011
/ Description:
/ Parameters: gets the stand to take a new  set of aircraft types accomodateable by the stand 
/ Return: none
------------------------------------------------------------*/	
void GateStand::setTypeList(std::list<AircraftType>* _typeList){
	typeList = _typeList;
}

/*------------------------------------------------------------
/ 
/ By: Trevor
/ Date: February 29 2011
/ Description: adds a new type of aircraft accomodateable by the stand 
/ Parameters:	a pointer to a list of aircraftTypes
/ Return: none
------------------------------------------------------------*/	
void GateStand::addAircraftType(AircraftType* _type){
	typeList->push_back(*_type);
}
	


/*------------------------------------------------------------
/ 
/ By: Trevor
/ Date: February 29 2011
/ Description: 
/ Parameters: none
/ Return:returns a pointer to a list of flights currently stacked up over this stand
------------------------------------------------------------*/	
std::list<Flight>* GateStand::getAccomodationList (void){
	return accomodationList;
}


/*------------------------------------------------------------
/ 
/ By: Trevor
/ Date: February 29 2011
/ Description:  
/ Parameters: a pointer to a list of flights to be assigned to the stand
/ Return: none
------------------------------------------------------------*/	
void GateStand::setAccodmodationList(std::list<Flight>* _accomodationList){
	accomodationList = _accomodationList;
}

/*------------------------------------------------------------
/ 
/ By: Trevor
/ Date: February 29 2011
/ Description: adds a flight to a stands accomodation list
/ Parameters: a pointer to a flight
/ Return: none
------------------------------------------------------------*/	
void GateStand::addToAccomodationList(Flight* _flight){
	accomodationList->push_back(*_flight);
}

/*------------------------------------------------------------
/ 
/ By: Trevor
/ Date: February 29 2011
/ Description: sets the stand ID 
/ Parameters: 
/ Return: 
------------------------------------------------------------*/	
void GateStand::setStandID(string id){
	standID = id;
=======
}

/*------------------------------------------------------------
/ setStandID
/ By: Mark Freedman
/ Date: February 26 2011
/ Description: changes the stands ID
/ Paramneters: N/A
/ Return: N/A
------------------------------------------------------------*/
void GateStand::setStandID(string id){
	standID = id;
>>>>>>> .r38
}